<?php
/**
 * Created by PhpStorm.
 * User: Thanh Lâm
 * Date: 4/17/14
 * Time: 1:26 PM
 */
namespace Phalconvn\Capcha;
use Phalcon\DI\Injectable;
class Recaptcha extends  Injectable{
    const RECAPTCHA_API_SERVER = 'http://www.google.com/recaptcha/api';
    const RECAPTCHA_API_SECURE_SERVER = 'https://www.google.com/recaptcha/api';
    const RECAPTCHA_VERIFY_SERVER = 'www.google.com';
    const RECAPTCHA_ERROR_KEY = 'To use reCAPTCHA you must get an API key from <a href="https://www.google.com/recaptcha/admin/create">https://www.google.com/recaptcha/admin/create</a>';
    const RECAPTCHA_ERROR_REMOTE_IP = 'For security reasons, you must pass the remote IP address to reCAPTCHA';
    public static $error = 'incorrect-captcha-sol';
    public static $is_valid = false;

    /** get capcha ra view
     * @param $publicKey
     * @param string $error
     * @param bool $useSSL
     * @return string
     */
    public static function get($publicKey, $error = '', $useSSL = false){
        // Merging method arguments with class fileds
        $publicKey = $publicKey or die(self::RECAPTCHA_ERROR_KEY);
        // Choosing a server
        $server = $useSSL ? self::RECAPTCHA_API_SECURE_SERVER : self::RECAPTCHA_API_SERVER;
        // Append an error
        if ($error) $error = "&amp;error=".$error;
        // Return HTML
        return '<script type="text/javascript" src="'.$server.'/challenge?k='.$publicKey.$error.'"></script>
                <noscript>
                <iframe src="'.$server.'/noscript?k='.$publicKey.$error.'" height="300" width="500" frameborder="0"></iframe><br/>
                <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
                <input type="hidden" name="recaptcha_response_field" value="manual_challenge"/>
                </noscript>';
    }

    /** kiem tra nhap capcha
     * @param $privateKey
     * @param $remoteIP
     * @param $challenge
     * @param $response
     * @param array $extra_params
     * @return bool
     */
    public static function check($privateKey, $remoteIP, $challenge, $response, $extra_params = array()){
        $privateKey = $privateKey or die(self::RECAPTCHA_ERROR_KEY);
        $remoteIP = $remoteIP or die(self::RECAPTCHA_ERROR_REMOTE_IP);
        // Discard spam submissions
        if (!$challenge or !$response)
            return self::$is_valid;
        $response = self::httpPost(self::RECAPTCHA_VERIFY_SERVER, "/recaptcha/api/verify", array(
                'privatekey' => $privateKey,
                'remoteip' => $remoteIP,
                'challenge' => $challenge,
                'response' => $response
            ) + $extra_params);
        $answers = explode("\n", $response[1]);
        if (trim($answers[0]) == 'true') self::$is_valid = true;
        else self::$error = $answers[1];
        return self::$is_valid;
    }

    /** post len server
     * @param $host
     * @param $path
     * @param $data
     * @param int $port
     * @return array|string
     */
    private static function httpPost($host, $path, $data, $port = 80){
        $req = self::qsEncode($data);
        $http_request = "POST $path HTTP/1.0\r\n";
        $http_request .= "Host: $host\r\n";
        $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";
        $http_request .= "Content-Length: ".strlen($req)."\r\n";
        $http_request .= "User-Agent: reCAPTCHA/PHP\r\n";
        $http_request .= "\r\n";
        $http_request .= $req;
        $response = '';
        if (!($fs = @fsockopen($host, $port, $errno, $errstr, 10))) {
            die('Could not open socket');
        }
        fwrite($fs, $http_request);
        while (!feof($fs)) $response .= fgets($fs, 1160); // One TCP-IP packet
        fclose($fs);
        $response = explode("\r\n\r\n", $response, 2);
        return $response;
    }

    /** mã hoa code gui di
     * @param $data
     * @return string
     */
    private static function qsEncode($data){
        $req = '';
        foreach ($data as $key => $value)
            $req .= $key.'='.urlencode(stripslashes($value)).'&';
        // Cut the last '&'
        $req = substr($req, 0, strlen($req) - 1);
        return $req;
    }
}